package craky.keeper.client.task;

import java.text.MessageFormat;

import android.app.Activity;
import android.os.AsyncTask;
import craky.keeper.bean.Category;
import craky.keeper.bean.Income;
import craky.keeper.bean.KeeperObject;
import craky.keeper.bean.Pay;
import craky.keeper.bean.ResultSet;
import craky.keeper.client.DetailActivity;
import craky.keeper.client.KeeperActivity;
import craky.keeper.client.R;
import craky.keeper.util.KeeperUtil;

public class KeeperTask extends AsyncTask<Boolean, String, ResultSet>
{
    private Activity activity;

    private KeeperObject oldData, newData;

    private String action;

    private boolean isPay, isAdd;

    private String errorMessage;

    public KeeperTask(Activity activity, KeeperObject oldData, KeeperObject newData, String action)
    {
        this.activity = activity;
        this.oldData = oldData;
        this.newData = newData;
        this.action = action;
    }

    @Override
    protected ResultSet doInBackground(Boolean...params)
    {
        ResultSet resultSet = null;

        try
        {
            if(action.equals(KeeperUtil.ACTION_DELETE))
            {
                this.isPay = params[0];
                resultSet = delete();
            }
            else
            {
                this.isPay = params[0];
                this.isAdd = params[1];
                resultSet = addOrModify();
            }
        }
        catch(Exception e)
        {
            this.errorMessage = activity.getResources().getString(R.string.connection_error);
        }

        return resultSet;
    }

    @Override
    protected void onPostExecute(ResultSet resultSet)
    {
        if(action.equals(KeeperUtil.ACTION_DELETE))
        {
            ((KeeperActivity)activity).getCurrentList().dealDeleteResult(this, errorMessage, resultSet);
        }
        else
        {
            ((DetailActivity)activity).dealOperationResult(this, errorMessage, resultSet);
        }
    }

    private ResultSet addOrModify()
    {
        ResultSet resultSet = null;
        String oldType = null;
        String newType = null;

        if(isAdd)
        {
            newType = newData.getType();
        }
        else if((oldType = oldData.getType()).equals(newType = newData.getType()))
        {
            oldType = null;
            newType = null;
        }

        if(newType != null && !KeeperUtil.remote.existCategory(isPay, newType))
        {
            errorMessage = activity.getResources().getString(R.string.type_not_exists);
            errorMessage = MessageFormat.format(errorMessage, newType);
            KeeperUtil.removeCategory(newType, isPay);
            ((DetailActivity)activity).clearInputType();
        }
        else
        {
            if(isAdd)
            {
                Category category = KeeperUtil.getCategory(newType, isPay);

                if(isPay)
                {
                    resultSet = KeeperUtil.remote.addPay((Pay)newData, category);
                }
                else
                {
                    resultSet = KeeperUtil.remote.addIncome((Income)newData, category);
                }
            }
            else
            {
                Category oldCategory = oldType == null? null: KeeperUtil.getCategory(oldType, isPay);
                Category newCategory = newType == null? null: KeeperUtil.getCategory(newType, isPay);

                if(isPay)
                {
                    resultSet = KeeperUtil.remote.updatePay((Pay)newData, oldCategory, newCategory);
                }
                else
                {
                    resultSet = KeeperUtil.remote.updateIncome((Income)newData, oldCategory, newCategory);
                }
            }
        }

        return resultSet;
    }

    private ResultSet delete()
    {
        ResultSet resultSet;
        Category category = KeeperUtil.getCategory(newData.getType(), isPay);

        if(isPay)
        {
            resultSet = KeeperUtil.remote.deletePay((Pay)newData, category);
        }
        else
        {
            resultSet = KeeperUtil.remote.deleteIncome((Income)newData, category);
        }

        return resultSet;
    }
}